/**
 * 中文函数封装 (zh-function.js)
 * 支持函数操作、延迟执行、节流、防抖等功能
 * 中文方法命名 + JSDoc 参数提示
 */

class 函数 {
  /**
   * 构造函数 - 创建函数封装实例
   * @param {Function} 函数 要封装的函数
   */
  constructor(函数) {
    if (typeof 函数 !== 'function') {
      throw new TypeError('必须提供一个函数');
    }
    this._函数 = 函数;
  }

  /**
   * 获取原始函数
   * @returns {Function} 原始函数
   */
  取值() {
    return this._函数;
  }

  /**
   * 调用函数
   * @param {*} 上下文 函数执行上下文
   * @param {...*} 参数 函数参数
   * @returns {*} 函数执行结果
   */
  调用(上下文, ...参数) {
    return this._函数.apply(上下文, 参数);
  }

  /**
   * 延迟执行函数
   * @param {number} 延迟毫秒 延迟时间（毫秒）
   * @param {...*} 参数 函数参数
   * @returns {Object} 包含清除方法的对象
   */
  延迟执行(延迟毫秒, ...参数) {
    const 定时器 = setTimeout(() => {
      this._函数(...参数);
    }, 延迟毫秒);
    return {
      清除: () => clearTimeout(定时器)
    };
  }

  /**
   * 创建节流函数
   * @param {number} 间隔毫秒 执行间隔（毫秒）
   * @param {boolean} [立即执行=true] 是否立即执行首次调用
   * @returns {函数} 节流后的函数实例
   */
  节流(间隔毫秒, 立即执行 = true) {
    let 上次执行时间 = 0;
    let 定时器 = null;
    
    const 节流函数 = (...参数) => {
      const 当前时间 = Date.now();
      
      if (立即执行 && !上次执行时间) {
        this._函数.apply(this, 参数);
        上次执行时间 = 当前时间;
        return;
      }
      
      if (当前时间 - 上次执行时间 >= 间隔毫秒) {
        if (定时器) {
          clearTimeout(定时器);
          定时器 = null;
        }
        this._函数.apply(this, 参数);
        上次执行时间 = 当前时间;
      } else if (!定时器) {
        定时器 = setTimeout(() => {
          上次执行时间 = Date.now();
          定时器 = null;
          this._函数.apply(this, 参数);
        }, 间隔毫秒 - (当前时间 - 上次执行时间));
      }
    };
    
    return new 函数(节流函数);
  }

  /**
   * 创建防抖函数
   * @param {number} 等待毫秒 等待时间（毫秒）
   * @param {boolean} [立即执行=false] 是否立即执行首次调用
   * @returns {函数} 防抖后的函数实例
   */
  防抖(等待毫秒, 立即执行 = false) {
    let 定时器 = null;
    
    const 防抖函数 = (...参数) => {
      if (定时器) {
        clearTimeout(定时器);
      }
      
      if (立即执行 && !定时器) {
        this._函数.apply(this, 参数);
      }
      
      定时器 = setTimeout(() => {
        if (!立即执行) {
          this._函数.apply(this, 参数);
        }
        定时器 = null;
      }, 等待毫秒);
    };
    
    return new 函数(防抖函数);
  }

  /**
   * 绑定函数上下文
   * @param {*} 上下文 绑定的上下文
   * @param {...*} 前置参数 预设参数
   * @returns {函数} 绑定后的函数实例
   */
  绑定(上下文, ...前置参数) {
    return new 函数(this._函数.bind(上下文, ...前置参数));
  }

  /**
   * 前置包装函数
   * @param {Function} 前置函数 前置执行的函数
   * @returns {函数} 包装后的函数实例
   */
  前置包装(前置函数) {
    const 原函数 = this._函数;
    const 包装函数 = function(...参数) {
      前置函数.apply(this, 参数);
      return 原函数.apply(this, 参数);
    };
    return new 函数(包装函数);
  }

  /**
   * 后置包装函数
   * @param {Function} 后置函数 后置执行的函数
   * @returns {函数} 包装后的函数实例
   */
  后置包装(后置函数) {
    const 原函数 = this._函数;
    const 包装函数 = function(...参数) {
      const 结果 = 原函数.apply(this, 参数);
      后置函数.apply(this, 参数);
      return 结果;
    };
    return new 函数(包装函数);
  }

  /**
   * 创建重试函数
   * @param {number} 最大次数 最大重试次数
   * @param {number} [间隔毫秒=1000] 重试间隔（毫秒）
   * @returns {函数} 重试函数实例
   */
  重试(最大次数, 间隔毫秒 = 1000) {
    return new 函数(async (...参数) => {
      let 重试次数 = 0;
      while (true) {
        try {
          return await this._函数(...参数);
        } catch (错误) {
          重试次数++;
          if (重试次数 >= 最大次数) {
            throw 错误;
          }
          await new Promise(resolve => setTimeout(resolve, 间隔毫秒));
        }
      }
    });
  }

  /**
   * 创建结果缓存函数
   * @returns {函数} 缓存函数实例
   */
  缓存() {
    const 缓存 = new Map();
    const 原函数 = this._函数;
    
    const 缓存函数 = (...参数) => {
      const 键 = JSON.stringify(参数);
      if (缓存.has(键)) {
        return 缓存.get(键);
      }
      const 结果 = 原函数(...参数);
      缓存.set(键, 结果);
      return 结果;
    };
    
    return new 函数(缓存函数);
  }

  /**
   * 创建带超时控制的函数
   * @param {number} 超时毫秒 超时时间（毫秒）
   * @param {Error} [超时错误=new Error('函数执行超时')] 超时错误对象
   * @returns {函数} 带超时控制的函数实例
   */
  超时控制(超时毫秒, 超时错误 = new Error('函数执行超时')) {
    return new 函数((...参数) => {
      return new Promise((resolve, reject) => {
        const 定时器 = setTimeout(() => {
          reject(超时错误);
        }, 超时毫秒);
        
        try {
          const 结果 = this._函数(...参数);
          clearTimeout(定时器);
          resolve(结果);
        } catch (错误) {
          clearTimeout(定时器);
          reject(错误);
        }
      });
    });
  }

  /** 静态方法 */

  /**
   * 静态方法：判断是否为函数
   * @static
   * @param {*} v 要检查的值
   * @returns {boolean} 是否为函数
   */
  static 是否函数(v) {
    return typeof v === 'function';
  }

  /**
   * 静态方法：创建空函数
   * @static
   * @returns {函数} 空函数实例
   */
  static 空() {
    return new 函数(() => {});
  }

  /**
   * 静态方法：创建恒等函数
   * @static
   * @returns {函数} 恒等函数实例
   */
  static 恒等() {
    return new 函数(x => x);
  }

  /**
   * 静态方法：组合函数（从右到左）
   * @static
   * @param {...Function} 函数列表 要组合的函数列表
   * @returns {函数} 组合后的函数实例
   */
  static 组合(...函数列表) {
    return new 函数(函数列表.reduce((a, b) => (...参数) => a(b(...参数))));
  }

  /**
   * 静态方法：管道函数（从左到右）
   * @static
   * @param {...Function} 函数列表 要组合的函数列表
   * @returns {函数} 管道函数实例
   */
  static 管道(...函数列表) {
    return new 函数(函数列表.reduce((a, b) => (...参数) => b(a(...参数))));
  }
}



// CommonJS 导出

  module.exports = {
    函数,
    default: 函数
  };
  module.exports.函数 = 函数;


// ES 模块导出
// export { 函数 };
// export default 函数;